package zemberek3.crosscheck;

import com.google.common.collect.*;
import com.google.common.io.Resources;
import org.jcaki.SimpleTextWriter;
import zemberek3.lexicon.DictionaryItem;
import zemberek3.lexicon.RootLexicon;
import zemberek3.lexicon.tr.TurkishDictionaryLoader;
import zemberek3.lexicon.tr.TurkishSuffixes;
import zemberek3.shared.lexicon.PrimaryPos;
import zemberek3.structure.Turkish;

import java.io.File;
import java.io.IOException;
import java.text.Collator;
import java.util.*;

public class MissingLemmaCheck {

    TurkishSuffixes suffixes = new TurkishSuffixes();
    Multimap<String, ValidationDictionaryGenerator.SubUnit> tdkMap = HashMultimap.create();
    Multimap<String, DictionaryItem> z3Map = HashMultimap.create();

    public MissingLemmaCheck() throws IOException {
        ValidationDictionaryGenerator.TdkDictionary dictionary = ValidationDictionaryGenerator.getDictionaryFromXml(
                new File("/home/kodlab/data/lm/unknowns/tdk-dic.xml"));


        for (ValidationDictionaryGenerator.DictionaryUnit unit : dictionary.units) {
            for (ValidationDictionaryGenerator.SubUnit subUnit : unit.subUnits)
                tdkMap.put(unit.name, subUnit);
        }

        RootLexicon items = TurkishDictionaryLoader.loadDefaultDictionaries(suffixes);

        for (DictionaryItem item : items) {
            if (!tdkMap.containsKey(item.lemma) && item.primaryPos == PrimaryPos.Duplicator) {
                System.out.println("Not in TDK:" + item);
            }
        }

        for (DictionaryItem item : items) {
            z3Map.put(item.lemma, item);
        }
    }

    static List<String> exclude = Lists.newArrayList(
            "leşme", "leşmek", "laşma", "laşmak", "lük", "lik", "luk", "lık", "sız", "me", "ma", "ılmak", "ilmek", "ülmek", "ulmak",
            "lu", "li", "sız", "siz", "lı", "lü", "süz", "suz", "lenmek", "lanmak", "ci", "cı", "cü", "cu", "ış", "iş", "üş", "uş", "ce",
            "unmak", "çı", "çi", "çu", "çü", "laştırmak", "leştirmek", "lendirmek", "landırmak", "ça", "çe", "ca", "tmak", "tmek",
            "tırmak", "tirmek", "turmak", "türmek", "dırmak", "dirmek", "durmak", "dürmek",
            "sel", "sal", "ımsı", "imsi", "ümsü", "umsu", "msı", "msi", "msü", "msu", "cık", "cik", "cuk", "cük", "çık", "çik", "çuk", "çük"
    );

    public void findMissingTypesInZ3() throws IOException {

        Map<String, PrimaryPos> tdkPosMap = Maps.newHashMap();

        tdkPosMap.put("isim", PrimaryPos.Noun);
        tdkPosMap.put("fiil", PrimaryPos.Verb);
        tdkPosMap.put("sıfat", PrimaryPos.Adjective);
        tdkPosMap.put("bağlaç", PrimaryPos.Conjunction);
        tdkPosMap.put("ünlem", PrimaryPos.Interjection);
        tdkPosMap.put("zarf", PrimaryPos.Adverb);
        tdkPosMap.put("zamir", PrimaryPos.Pronoun);

        Set<String> notInZ3 = Sets.newHashSet();
        Set<String> notInTdk = Sets.newHashSet();
        for (String lemma : tdkMap.keySet()) {
            if (lemma.equals("yiğit"))
                System.out.println();

            if (!z3Map.containsKey(lemma))
                continue;
            Collection<DictionaryItem> its = z3Map.get(lemma);
            HashSet<PrimaryPos> poss = Sets.newHashSet();
            for (DictionaryItem it : its) {
                poss.add(it.primaryPos);
            }
            HashSet<PrimaryPos> possTdk = Sets.newHashSet();
            List<ValidationDictionaryGenerator.SubUnit> units = Lists.newArrayList(tdkMap.get(lemma));

            String attrs = "";

            for (ValidationDictionaryGenerator.SubUnit unit : units) {
                PrimaryPos tdkPos = tdkPosMap.get(unit.pos);
                if (tdkPos != null)
                    possTdk.add(tdkPos);
            }

            for (PrimaryPos primaryPos : possTdk) {
                if (!poss.contains(primaryPos)) {
                    if (primaryPos == PrimaryPos.Adjective && poss.contains(PrimaryPos.Numeral))
                        continue;
                    if (primaryPos == PrimaryPos.Adjective && poss.contains(PrimaryPos.Duplicator))
                        continue;
                    if (primaryPos != PrimaryPos.Noun && primaryPos != PrimaryPos.Verb)
                        attrs = "[P:" + primaryPos.shortForm + "]";
                    else
                        attrs = "";
                    String x = lemma + " " + attrs;
                    notInZ3.add(x.trim());
                }
            }

            for (PrimaryPos primaryPos : poss) {
                if (primaryPos == PrimaryPos.PostPositive || primaryPos == PrimaryPos.Numeral)
                    continue;
                if (!possTdk.contains(primaryPos)) {
                    if (primaryPos == PrimaryPos.Numeral && possTdk.contains(PrimaryPos.Adjective))
                        continue;
                    if (primaryPos == PrimaryPos.Duplicator && possTdk.contains(PrimaryPos.Adjective))
                        continue;
                    if (primaryPos != PrimaryPos.Noun && primaryPos != PrimaryPos.Verb)
                        attrs = "[P:" + primaryPos.shortForm + "]";
                    else
                        attrs = "";
                    String x = lemma + " " + attrs;
                    notInTdk.add(x.trim());
                }
            }
        }
        List<String> uniqueSorted = Lists.newArrayList(notInZ3);
        Collections.sort(uniqueSorted, Turkish.COLLATOR);
        SimpleTextWriter.oneShotUTF8Writer(new File(Resources.getResource("tr/z3-missing-types.txt").getFile())).writeLines(uniqueSorted);

        List<String> uniqueSorted2 = Lists.newArrayList(notInTdk);
        Collections.sort(uniqueSorted2, Turkish.COLLATOR);
        SimpleTextWriter.oneShotUTF8Writer(new File(Resources.getResource("tr/tdk-missing-types.txt").getFile())).writeLines(uniqueSorted2);
    }

    public void findMissingItemsInZ3() throws IOException {

        Map<String, String> tdkPosMap = Maps.newHashMap();

        tdkPosMap.put("sıfat", "[P:Adj]");
        tdkPosMap.put("bağlaç", "[P:Conj]");
        tdkPosMap.put("ünlem", "[P:Interj]");
        tdkPosMap.put("zarf", "[P:Adv]");

        Set<String> dictionaryLines = Sets.newHashSet();
        for (String lemma : tdkMap.keySet()) {
            if (!z3Map.containsKey(lemma)) {
                boolean found = false;
                for (String s : exclude) {
                    if (lemma.endsWith(s)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    List<ValidationDictionaryGenerator.SubUnit> units = Lists.newArrayList(tdkMap.get(lemma));
                    for (ValidationDictionaryGenerator.SubUnit unit : units) {
                        String attrs = tdkPosMap.get(unit.pos);
                        if (attrs == null)
                            attrs = "";
                        dictionaryLines.add(lemma + " " + attrs);
                    }
                }
            }
        }
        List<String> uniqueSorted = Lists.newArrayList(dictionaryLines);
        Collections.sort(uniqueSorted, Collator.getInstance(new Locale("tr")));
        SimpleTextWriter.oneShotUTF8Writer(new File(Resources.getResource("tr/z2-missing.txt").getFile())).writeLines(uniqueSorted);
    }

    public static void main(String[] args) throws IOException {
        new MissingLemmaCheck().findMissingTypesInZ3();

    }

}
